package top.xunfong.file.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import top.xunfong.file.constant.FileConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Stream;

/**
 * 文件上传工具类
 */
public class FileUploadUtil {

    // 编码文件格式
    private static final String EXTRACT_FILE_FORMAT = "{}/{}.{}";

    private static final String EXTRACT_FILE_FORMAT_GROUP = "{}/{}/{}";

    // 编码文件格式, 带序列号
    private static final String EXTRACT_FILE_SEQ_FORMAT = "{}/{}_{}.{}";

    private static final String EXTRACT_FILE_NAME_FORMAT = "{}.{}";

    private static final String EXTRACT_FILE_FORMAT_GROUP_SEQ = "{}";

    private static final String BASE_DIR = FileConstants.PATH_SEPARATOR;

    /**
     * 文件保存到磁盘
     *
     * @param file
     * @param baseDir
     * @return
     */
    public static File fileToBaseDir(MultipartFile file, String baseDir) throws IOException {
        return FileUtil.writeBytes(file.getBytes(), baseDir);
    }


    /**
     * 编码文件名，包含相对路径
     */
    public static String extractFilename(MultipartFile file) {
        return getUniversalFilePath(StrUtil.format(EXTRACT_FILE_NAME_FORMAT, UUID.randomUUID().toString(),
                FileNameUtil.getSuffix(file.getOriginalFilename())));
    }

//    /**
//     * 获取文件路径，包含文件名
//     *
//     * @return
//     */
//    public static String getFilePath(String suffix) {
//        return StrUtil.format(EXTRACT_FILE_FORMAT, DateUtil.format(new Date(), "yyyy/MM/dd"),
//                UUID.randomUUID(), suffix);
//    }

//    public static String getFilePathByGroup(String group) {
//        return StrUtil.format(EXTRACT_FILE_FORMAT_GROUP, DateUtil.format(new Date(), "yyyy/MM/dd"),
//                group,
//                UUID.randomUUID());
//    }

    /**
     * 多级目录文件夹路径
     * 年/月/日/paths
     * paths 如果传空，则为文件夹，这儿不做校验
     *
     * @param paths
     * @return
     */
    public static String getUniversalFilePath(String... paths) {
        String format = String.join("/", new ArrayList<>(Collections.nCopies(paths.length + 1, EXTRACT_FILE_FORMAT_GROUP_SEQ)));
        Object[] args = Stream.concat(Stream.of(DateUtil.format(new Date(), "yyyy/MM/dd")), Stream.of(paths))
                .toArray(String[]::new);
        return StrUtil.format(format, args);
    }

    /**
     * 重写文件名
     *
     * @return
     */
    public static String getFileName(String suffix) {
        if (StringUtils.isBlank(suffix)) {
            return UUID.randomUUID().toString();
        }
        return StrUtil.format("{}.{}", UUID.randomUUID(), suffix);
    }

    public static String getFolderPathByGroup(String group) {

        return StrUtil.format(EXTRACT_FILE_FORMAT_GROUP, DateUtil.format(new Date(), "yyyy/MM/dd"),
                group);
    }

    /**
     * 校验文件md5
     *
     * @param filePath
     * @param md5
     * @return
     */
    public static Boolean checkFileMD5(String filePath, String md5) {
        if (StringUtils.isNotBlank(filePath) && StringUtils.isNotBlank(md5)) {
            return md5.equals(DigestUtil.md5Hex(new File(filePath)));
        }
        return false;
    }

    public static String concatPath(String... paths) {
        if (ObjectUtil.isNotNull(paths) && paths.length > 0) {
            String join = String.join("/", paths);
            // 移除多余的 /
            return join.replaceAll("/+", "/");
        }
        return "";
    }
}